package manager

import (
	"BlazeRider-backend/app/db"
	"database/sql"
	"fmt"
	"log"
	"sync"
)

// ClientErrorRecordMysqlStorage 管理礼物赠送记录
// GiftRecord 表示单个礼物的赠送记录
type GiftRecordMysqlInfo struct {
	MsgId         string       `db:"msg_id"`
	LiveRoomId    string       `db:"live_room_id"`
	Times         int          `db:"times"`
	Track         int          `db:"track"`
	UserId        string       `db:"user_id"`
	GiftId        string       `db:"gift_id"`
	GiftName      string       `db:"gift_name"`
	Amount        int          `db:"amount"`
	OneValue      int          `db:"one_value"`
	TotalValue    int          `db:"total_value"`
	Score         int          `db:"score"`
	TotalScore    int          `db:"total_score"`
	GiftLevel     int          `db:"gift_level"`
	GiftUpgrading int          `db:"gift_upgrading"`
	CreateAt      sql.NullTime `db:"create_at"` // 使用 NullTime
	UpdateAt      sql.NullTime `db:"update_at"` // 使用 NullTime
}

// GiftRecordWithUserInfoMysqlInfo 表示单个礼物的赠送记录与用户相关联的数据
type GiftRecordWithUserInfoMysqlInfo struct {
	MsgId         string       `db:"msg_id"`
	LiveRoomId    string       `db:"live_room_id"`
	Times         int          `db:"times"`
	Track         int          `db:"track"`
	Job           int          `db:"job"`
	UserId        string       `db:"user_id"`
	GiftId        string       `db:"gift_id"`
	GiftName      string       `db:"gift_name"`
	Amount        int          `db:"amount"`
	OneValue      int          `db:"one_value"`
	TotalValue    int          `db:"total_value"`
	Score         int          `db:"score"`
	TotalScore    int          `db:"total_score"`
	GiftLevel     int          `db:"gift_level"`
	GiftUpgrading int          `db:"gift_upgrading"`
	UserName      string       `db:"user_name"`
	UserHeadImg   string       `db:"head_img"`
	UserLevel     int          `db:"level"`
	UserScore     int          `db:"score"`
	ExpireAt      sql.NullTime `db:"expire_at"`
	CreateAt      sql.NullTime `db:"create_at"` // 使用 NullTime
	UpdateAt      sql.NullTime `db:"update_at"` // 使用 NullTime
}

type GiftRecordMysqlStorage struct {
	roomGiftRecords map[string]map[string][]GiftRecord
	db              *sql.DB
	mu              sync.Mutex
}

func NewGiftRecordMysqlStorage() (*GiftRecordMysqlStorage, error) {
	return &GiftRecordMysqlStorage{
		roomGiftRecords: make(map[string]map[string][]GiftRecord),
	}, nil
}

// AddGiftRecord 增加礼物赠送记录
func (grm *GiftRecordMysqlStorage) GetGiftRecordByMsgId(msgID string) (*GiftRecordMysqlInfo, error) {
	// 定义一个变量来存储查询结果
	var giftRecordMysqlInfo GiftRecordMysqlInfo

	// 执行 SQL 查询
	err := db.GetDB().QueryRow(`
        SELECT msg_id, live_room_id, times, user_id, gift_id, gift_name, amount, one_value, total_value, score, total_score, gift_level, gift_upgrading, create_at, update_at
        FROM gift_records
        WHERE msg_id = ?
		Limit 1
    `, msgID).Scan(
		&giftRecordMysqlInfo.MsgId,
		&giftRecordMysqlInfo.LiveRoomId,
		&giftRecordMysqlInfo.Times,
		&giftRecordMysqlInfo.UserId,
		&giftRecordMysqlInfo.GiftId,
		&giftRecordMysqlInfo.GiftName,
		&giftRecordMysqlInfo.Amount,
		&giftRecordMysqlInfo.OneValue,
		&giftRecordMysqlInfo.TotalValue,
		&giftRecordMysqlInfo.Score,
		&giftRecordMysqlInfo.TotalScore,
		&giftRecordMysqlInfo.GiftLevel,
		&giftRecordMysqlInfo.GiftUpgrading,
		&giftRecordMysqlInfo.CreateAt,
		&giftRecordMysqlInfo.UpdateAt,
	)

	// 处理错误
	if err != nil {
		if err == sql.ErrNoRows {
			log.Printf("No live room found by msgId: %s", msgID)
			return nil, err // 没有找到数据，返回 ErrNoRows
		}
		log.Printf("Error querying get gift record by msgId: %v", err) // 打印其他错误信息
		return nil, err                                                // 返回其他错误
	}

	// 查询成功，返回结果
	return &giftRecordMysqlInfo, nil
}

// AddGiftRecord 增加礼物赠送记录
func (grm *GiftRecordMysqlStorage) AddGiftRecord(msgID, liveRoomID, userID, giftID, giftName string, giftValue, giftScore, amount, times, giftLevel, giftUpgrading, track, job int) error {
	_, err := db.GetDB().Exec(`
		INSERT INTO gift_records 
			(msg_id, live_room_id, times, track, job, user_id, gift_id, gift_name, amount, one_value, total_value, score, total_score, gift_level, gift_upgrading, create_at, update_at)
		VALUES 
			(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
	`,
		msgID, liveRoomID, times, track, job, userID, giftID, giftName, amount, giftValue, giftValue*amount, giftScore, giftScore*amount, giftLevel, giftUpgrading) // 更新值参数

	if err != nil {
		return fmt.Errorf("create gift records error : %v", err)
	}
	return nil
}

// 查询本局最后一次该礼物信息
func (grm *GiftRecordMysqlStorage) GetLastGiftRecordByUserIdAndGiftId(liveRoomID string, times int, userId string, gift_id string) (*GiftRecordMysqlInfo, error) {
	// 定义一个变量来存储查询结果
	var giftRecordMysqlInfo GiftRecordMysqlInfo

	// 执行 SQL 查询
	err := db.GetDB().QueryRow(`
        SELECT msg_id, live_room_id, times, user_id, gift_id, gift_name, amount, one_value, total_value, score, total_score, gift_level, gift_upgrading, create_at, update_at
        FROM gift_records
        WHERE live_room_id = ? and
        times = ? and
        user_id = ? and
        gift_id = ? 
		ORDER BY create_at DESC
		Limit 1
    `, liveRoomID, times, userId, gift_id).Scan(
		&giftRecordMysqlInfo.MsgId,
		&giftRecordMysqlInfo.LiveRoomId,
		&giftRecordMysqlInfo.Times,
		&giftRecordMysqlInfo.UserId,
		&giftRecordMysqlInfo.GiftId,
		&giftRecordMysqlInfo.GiftName,
		&giftRecordMysqlInfo.Amount,
		&giftRecordMysqlInfo.OneValue,
		&giftRecordMysqlInfo.TotalValue,
		&giftRecordMysqlInfo.Score,
		&giftRecordMysqlInfo.TotalScore,
		&giftRecordMysqlInfo.GiftLevel,
		&giftRecordMysqlInfo.GiftUpgrading,
		&giftRecordMysqlInfo.CreateAt,
		&giftRecordMysqlInfo.UpdateAt,
	)

	// 处理错误
	if err != nil {
		if err == sql.ErrNoRows {
			log.Printf("No live room in GetLastGiftRecordByUserIdAndGiftId found with ID: %s", liveRoomID)
			return nil, err // 没有找到数据，返回 ErrNoRows
		}
		log.Printf("Error querying GetLastGiftRecordByUserIdAndGiftId : %v", err) // 打印其他错误信息
		return nil, err                                                           // 返回其他错误
	}

	// 查询成功，返回结果
	return &giftRecordMysqlInfo, nil
}

// 查询本局最后一次该礼物信息
func (grm *GiftRecordMysqlStorage) GetGiftCountByUserAndGiftId(liveRoomID string, times int, userID, giftId string) (int, error) {
	// 定义一个变量来存储查询结果
	//var giftRecordMysqlInfo GiftRecordMysqlInfo

	var sumAmount int

	// 执行 SQL 查询
	err := db.GetDB().QueryRow(`
        SELECT SUM(amount)
        FROM gift_records
        WHERE live_room_id = ? and
        times = ? and
        user_id = ? and
        gift_id = ? 
    `, liveRoomID, times, userID, giftId).Scan(
		&sumAmount,
	)

	// 处理错误
	if err != nil {
		if err == sql.ErrNoRows {
			log.Printf("No live room found in GetGiftCountByUserAndGiftId with ID: %s", liveRoomID)
			return 0, err // 没有找到数据，返回 ErrNoRows
		}
		log.Printf("Error querying GetGiftCountByUserAndGiftId : %v", err) // 打印其他错误信息
		return 0, err                                                      // 返回其他错误
	}

	// 查询成功，返回结果
	return sumAmount, nil
}

// 查询本局最后一次该礼物信息
func (grm *GiftRecordMysqlStorage) GetTotalScoreByRoomId(liveRoomID string, times int) (int, error) {
	// 定义一个变量来存储查询结果
	var sumScore int

	// 执行 SQL 查询
	err := db.GetDB().QueryRow(`
        SELECT SUM(total_score)
        FROM gift_records
        WHERE live_room_id = ? and
        times = ? 
    `, liveRoomID, times).Scan(
		&sumScore,
	)

	// 处理错误
	if err != nil {
		if err == sql.ErrNoRows {
			log.Printf("No live room found in GetTotalScoreByRoomId with ID: %s", liveRoomID)
			return 0, err // 没有找到数据，返回 ErrNoRows
		}
		log.Printf("Error querying GetTotalScoreByRoomId : %v, liveRoomID : %s, times : %d",
			err, liveRoomID, times) // 打印其他错误信息
		return 0, err // 返回其他错误
	}

	// 查询成功，返回结果
	return sumScore, nil
}

// 查询本局最后一次该礼物信息
func (grm *GiftRecordMysqlStorage) GetAccScoreByRoomIdAndUserId(liveRoomID string, times int, userId string) (int, error) {
	// 定义一个变量来存储查询结果
	var accScore int

	// 执行 SQL 查询
	err := db.GetDB().QueryRow(`
        SELECT SUM(total_score)
        FROM gift_records
        WHERE live_room_id = ? and
        times = ? and user_id = ?
        
    `, liveRoomID, times, userId).Scan(
		&accScore,
	)

	// 处理错误
	if err != nil {
		if err == sql.ErrNoRows {
			log.Printf("No live room found in GetAccScoreByRoomIdAndUserId with ID: %s", liveRoomID)
			return 0, err // 没有找到数据，返回 ErrNoRows
		}
		log.Printf("Error querying GetAccScoreByRoomIdAndUserId : %v, liveRoomID : %s, times : %d, userId : %s",
			err, liveRoomID, times, userId) // 打印其他错误信息
		return 0, err // 返回其他错误
	}

	// 查询成功，返回结果
	return accScore, nil
}

// GetGiftRecordByliveRoomAdnTrack 查询本局最后一次该礼物信息
func (grm *GiftRecordMysqlStorage) GetGiftRecordByLiveRoomAndTimes(liveRoomId string, times int) ([]GiftRecordMysqlInfo, error) {
	// 构建查询语句
	query := fmt.Sprintf(`
		SELECT msg_id, live_room_id, times, track, user_id, gift_id, 
			   gift_name, amount, one_value, total_value, 
			   score, total_score, gift_level, gift_upgrading, 
			   create_at, update_at
		FROM gift_records
		WHERE live_room_id = ? AND times = ? 
	`)

	// 准备查询参数
	args := make([]interface{}, 0, 2)
	args = append(args, liveRoomId)
	args = append(args, times)

	// 查询数据
	rows, err := db.GetDB().Query(query, args...)
	if err != nil {
		log.Printf("Error querying gift records: %v", err)
		return nil, err
	}
	defer rows.Close()

	// 遍历查询结果
	var giftRecordList []GiftRecordMysqlInfo
	for rows.Next() {
		var record GiftRecordMysqlInfo
		if err := rows.Scan(
			&record.MsgId,
			&record.LiveRoomId,
			&record.Times,
			&record.Track,
			&record.UserId,
			&record.GiftId,
			&record.GiftName,
			&record.Amount,
			&record.OneValue,
			&record.TotalValue,
			&record.Score,
			&record.TotalScore,
			&record.GiftLevel,
			&record.GiftUpgrading,
			&record.CreateAt,
			&record.UpdateAt,
		); err != nil {
			log.Printf("Error scanning gift record: %v", err)
			return nil, err
		}
		giftRecordList = append(giftRecordList, record)
	}

	// 检查是否查询到数据
	if len(giftRecordList) == 0 {
		log.Printf("No gift records found for live room ID: %s", liveRoomId)
		return nil, sql.ErrNoRows
	}

	return giftRecordList, nil
}

// GetGiftRecordByliveRoomAdnTrack 查询本局最后一次该礼物信息
func (grm *GiftRecordMysqlStorage) GetGiftRecordWithUserInfoByLiveRoomAndTimes(liveRoomId string, times int) ([]GiftRecordWithUserInfoMysqlInfo, error) {
	// 构建查询语句
	query := fmt.Sprintf(`
		SELECT grs.msg_id, grs.live_room_id, grs.times, grs.track, grs.job, grs.user_id, grs.gift_id, 
			   grs.gift_name, grs.amount, grs.one_value, grs.total_value, 
			   grs.score, grs.total_score, grs.gift_level, grs.gift_upgrading, 
			   us.user_name, us.head_img, us.level, us.score, us.expire_at,
			   grs.create_at, grs.update_at
		FROM gift_records grs 
		left join users us on us.user_id = grs.user_id
		WHERE grs.live_room_id = ? AND grs.times = ? 
	`)

	// 准备查询参数
	args := make([]interface{}, 0, 2)
	args = append(args, liveRoomId)
	args = append(args, times)

	// 查询数据
	rows, err := db.GetDB().Query(query, args...)
	if err != nil {
		log.Printf("Error querying gift records: %v", err)
		return nil, err
	}
	defer rows.Close()

	// 遍历查询结果
	var giftRecordList []GiftRecordWithUserInfoMysqlInfo
	for rows.Next() {
		var record GiftRecordWithUserInfoMysqlInfo
		if err := rows.Scan(
			&record.MsgId,
			&record.LiveRoomId,
			&record.Times,
			&record.Track,
			&record.Job,
			&record.UserId,
			&record.GiftId,
			&record.GiftName,
			&record.Amount,
			&record.OneValue,
			&record.TotalValue,
			&record.Score,
			&record.TotalScore,
			&record.GiftLevel,
			&record.GiftUpgrading,
			&record.UserName,
			&record.UserHeadImg,
			&record.UserLevel,
			&record.UserScore,
			&record.ExpireAt,
			&record.CreateAt,
			&record.UpdateAt,
		); err != nil {
			log.Printf("Error scanning gift record: %v", err)
			return nil, err
		}
		giftRecordList = append(giftRecordList, record)
	}

	// 检查是否查询到数据
	if len(giftRecordList) == 0 {
		log.Printf("No gift records found for live room ID: %s", liveRoomId)
		return nil, sql.ErrNoRows
	}

	return giftRecordList, nil
}

// GetGiftRecordWithUserInfoByLiveRoomAndTimesByTime 查询本场对局某个时间点后的记录
func (grm *GiftRecordMysqlStorage) GetGiftRecordWithUserInfoByLiveRoomAndTimesByTime(liveRoomId string, times int, timeStr string) ([]GiftRecordWithUserInfoMysqlInfo, error) {
	// 构建查询语句
	query := fmt.Sprintf(`
		SELECT grs.msg_id, grs.live_room_id, grs.times, grs.track, grs.user_id, grs.gift_id, 
			   grs.gift_name, grs.amount, grs.one_value, grs.total_value, 
			   grs.score, grs.total_score, grs.gift_level, grs.gift_upgrading, 
			   us.user_name, us.head_img, us.level, us.score, us.expire_at,
			   grs.create_at, grs.update_at
		FROM gift_records grs 
		left join users us on us.user_id = grs.user_id
		WHERE grs.live_room_id = ? AND grs.times = ? And grs.create_at >= ?
	`)

	// 准备查询参数
	args := make([]interface{}, 0, 3)
	args = append(args, liveRoomId)
	args = append(args, times)
	args = append(args, timeStr)

	// 查询数据
	rows, err := db.GetDB().Query(query, args...)
	if err != nil {
		log.Printf("Error querying gift records: %v", err)
		return nil, err
	}
	defer rows.Close()

	// 遍历查询结果
	var giftRecordList []GiftRecordWithUserInfoMysqlInfo
	for rows.Next() {
		var record GiftRecordWithUserInfoMysqlInfo
		if err := rows.Scan(
			&record.MsgId,
			&record.LiveRoomId,
			&record.Times,
			&record.Track,
			&record.UserId,
			&record.GiftId,
			&record.GiftName,
			&record.Amount,
			&record.OneValue,
			&record.TotalValue,
			&record.Score,
			&record.TotalScore,
			&record.GiftLevel,
			&record.GiftUpgrading,
			&record.UserName,
			&record.UserHeadImg,
			&record.UserLevel,
			&record.UserScore,
			&record.ExpireAt,
			&record.CreateAt,
			&record.UpdateAt,
		); err != nil {
			log.Printf("Error scanning gift record: %v", err)
			return nil, err
		}
		giftRecordList = append(giftRecordList, record)
	}

	return giftRecordList, nil
}

func (grm *GiftRecordMysqlStorage) SetGiftRecordLevel(msgId string, giftLevel, giftUpgrading int) error {
	_, err := db.GetDB().Exec(`
		update gift_records
		set gift_level = ?,
			gift_upgrading = ?,
			update_at = CURRENT_TIMESTAMP
		where
		    msg_id = ?
	`,
		giftLevel, giftUpgrading, msgId) // 更新值参数

	if err != nil {
		return fmt.Errorf("set live room error: %v", err)
	}
	return nil
}
